/*
 * AbstractAdmissionControl.cc
 *
 *  Created on: 2011-04-10
 *      Author: Jagger
 */

#include "AbstractAdmissionControl.h"

void AbstractAdmissionControl::initialize()
{
	totalIn = totalOut = 0;
	lastProcessTime = SIMTIME_ZERO;

	WATCH(totalIn);
	WATCH(totalOut);
}

void AbstractAdmissionControl::finish()
{
	recordScalar("admission:received", totalIn);
	recordScalar("admission:sent", totalOut);
	recordScalar("admission:discarded", totalIn - totalOut);
}

void AbstractAdmissionControl::handleMessage(cMessage* msg)
{
	if(msg->isSelfMessage())
	{
		NetPacket* pck = check_and_cast<NetPacket*>(msg);

		// Jesli pakiet spelnia nasz warunek to wysylamy go dalej, w przeciwnym
		// razie kasujemy go
		if(acceptPacket(pck))
		{
			// Uwzgledniamy opoznienie wynikajace z niedoskonalosci kanalu
			// wyjsciowego.
			cGate* out = gate("out");
			cChannel* channel = out->getChannel();
			if(channel)
			{
				simtime_t finishTime = channel->getTransmissionFinishTime();
				simtime_t delay = std::max(finishTime - simTime(), SIMTIME_ZERO);

				sendDelayed(pck, delay, out);
			}
			else
				send(pck, out);

			// Inkrementujemy liczbe wyslanych pakietow.
			totalOut++;
		}
		else
		{
			EV << "Packet " << pck->getName() << " discarded.\n";
			delete pck;
		}
	}
	else
	{
		// Nadchodzace pakiety obslugujemy z okreslonym opoznieniem
		simtime_t processDelay = par("processDelay");
		lastProcessTime = std::max(lastProcessTime + processDelay, simTime() + processDelay);
		scheduleAt(lastProcessTime, msg);

		// Inkrementujemy liczbe odebranych pakietow.
		totalIn++;
	}
}
